public void RecompressData(){

       //Chrono Trigger Recompression Routine

       //Reverse engineered by Michael Springer (evilpeer@hotmail.com)

       ushort j;

       ushort k;

       byte i;

       byte nBitCtr;        // Bit counter used for construction of Packet Header

       ushort nOffset;      // Byte offset in uncompressed data of pattern (counting backwards from current position)

       ushort nCopyLength;  // Number of bytes to copy when uncompressing

       uint nSrcPos;        // Byte position in uncompressed (source) data

       ushort nWorkPos;     // Byte position in compressed data

       ushort nPackHdrOff;  // Packet Header, constructed as source data is read

       byte[][] CompData = new byte[2][];

       ushort nCompSize = 0xFFFF;

       ushort nArrLength = 0;     // Final data length

       ushort nRange;              // The maximum range is either 0x0FFF or 0x07FF

       byte nMaxCopy;              // The maximum number of bytes to copy is either 18 or 34

 

       // External class variables, set by calling function.  May or may not be used

       // uint nSrcOff;            // Source starting offset

       // uint nWorkOff;           // Destination array starting offset

       // uint nCompressedSize;

       // uint nDecompressedSize;

       // byte[] WorkingBuffer;   // Destination array

       // byte[] SrcBuffer;        // Source array

 

       for(i = 0; i < 2; i++){

              nRange = (ushort) (0x07FF | (i << 11));

              nMaxCopy = (byte) (18 + ((1 - i) << 4));

              nSrcPos = 1;

              nBitCtr = 1;

              nOffset = 0;

              nCopyLength = 0;

              nWorkPos = 4;

              nPackHdrOff = 2;

              CompData[i] = new byte[0x10000];

              CompData[i][3] = SrcBuffer[nSrcOff];

             

                     while(nSrcPos < nDecompressedSize && nWorkPos < nCompSize){

                           for(; nBitCtr < 8 && nSrcPos < nDecompressedSize; nBitCtr++){

                                  if(nSrcPos > nRange){

                                         j = (ushort) (nSrcPos - nRange);

                                  }

                                  else{

                                         j = 0;

                                  }

                                  for(; j < nSrcPos; j++){

                                         for(k = 0; k < nMaxCopy && SrcBuffer[nSrcOff + j + k] == SrcBuffer[nSrcOff + nSrcPos + k]; k++){

                                         }

 

                                         if(k >= nCopyLength){

                                                nOffset = j;

                                                nCopyLength = k;

                                                if(k == nMaxCopy){

                                                       break;

                                                }

                                         }

                                  }

                                  if(nCopyLength > 2){

                                         CompData[i][nPackHdrOff] |= (byte) (1 << nBitCtr);

                                         nOffset = (ushort) (nSrcPos - nOffset);

                                         CompData[i][nWorkPos++] = (byte) (nOffset & 0xFF);

                                         CompData[i][nWorkPos++] = (byte) (((nCopyLength - 3) << (3 + i)) | ((nOffset >> 8) & (0x07 | (i << 3))));

                                         nSrcPos += nCopyLength;

                                         nCopyLength = 0;

                                  }

                                  else{

                                         CompData[i][nWorkPos++] = SrcBuffer[nSrcOff + nSrcPos++];

                                  }

                           }

                           if(nBitCtr == 8){

                                  nBitCtr = 0;

                                  nPackHdrOff = nWorkPos;

                                  nWorkPos++;

                           }

                     }

 

                     if(nWorkPos < nCompSize){

                           if(nBitCtr > 0){

CompData[i][nPackHdrOff] |= (byte) (0xFF << nBitCtr);

                                  Array.Copy(CompData[i], nPackHdrOff, CompData[i], nPackHdrOff + 3, nWorkPos - nPackHdrOff);

                                  CompData[i][nPackHdrOff] = (byte) (nBitCtr | (0xC0 * (i - 1)));

                                  nArrLength = (ushort) (nWorkPos + 3);

                                  CompData[i][nPackHdrOff + 1] = (byte) nArrLength;

                                  CompData[i][nPackHdrOff + 2] = (byte) (nArrLength >> 8);

                                  CompData[i][nWorkPos + 3] = 0;

                           }

                           else{

                                  nArrLength = (ushort) (nPackHdrOff + 1);

                                  CompData[i][nPackHdrOff] = (byte) (0xC0 * (i - 1));

                           }

 

                           nCompSize = (ushort) (nPackHdrOff - 2);

                           CompData[i][0] = (byte) (nCompSize & 0xFF);

                           CompData[i][1] = (byte) (nCompSize >> 8);

 

                           Array.Copy(CompData[i], 0, WorkingBuffer, nWorkOff, nArrLength + 1);

                           nCompressedSize = (uint) (nArrLength + 1);

                     }

              }

       }

}